/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*-  */
/*
 * catchit
 * Copyright (C) 2013 Ryan Grinkewitz <graphite@Toto>
 * 
 */

#include "game-state-manager.h"
#include <iomanip>

GameStateManager* GameStateManager::gameStateManagerInstance = NULL; 
	 
GameStateManager* GameStateManager::getInstance()
{
	if (!gameStateManagerInstance){ 
		gameStateManagerInstance = new GameStateManager;
	}
	 
	return gameStateManagerInstance;
}

void GameStateManager::resetManager(){
	delete levelGenerator;
	delete gameState;
	
	initializeState ();
}

void GameStateManager::initializeState(){
	
	levelGenerator = new LevelGenerator();
	gameState = new GameState();

	//std::cout << "Generating Level 0:" << std::endl;
	Level* currentLevel = levelGenerator->generateLevel(DIFFICULTY, LEVEL_SIZE, NULL);

	currentLevel->updateLevelYPosition (LEVEL_START_Y);
	gameState->insertLevel(currentLevel);

	for(int i = 1; i < GAME_SIZE - 1; i++){
		//std::cout << "Generating Level "<< i << ":" << std::endl;		
		Level* newLevel = levelGenerator->generateLevel(DIFFICULTY, LEVEL_SIZE, currentLevel);
		currentLevel = newLevel;
		currentLevel->updateLevelYPosition (-i * 32 + LEVEL_START_Y);
		gameState->insertLevel(currentLevel);
	}

	//generate a final level for completion
	currentLevel = levelGenerator->generateLevel(DIFFICULTY, LEVEL_SIZE, NULL);
	currentLevel->updateLevelYPosition (-(GAME_SIZE - 1) * 32 + LEVEL_START_Y);
	gameState->insertLevel(currentLevel);	
	           
	Player* player = new Player();
	player->setXPosition(PLAYER_START_X);
	player->setYPosition(START_Y);
	player->setIsOnPlatform(true);

	gameState->setPlayer(player);

	Computer* computer = new Computer();
	computer->setXPosition(COMPUTER_START_X);
	computer->setYPosition(START_Y);
	computer->setIsOnPlatform(true);

	gameState->setComputer(computer);

	gameWon = false;
	
}

GameState* GameStateManager::getGameState(){
	return gameState;
}

void GameStateManager::updateGamePosition(int velocity){
	int currentPosition = gameState->getGamePosition ();

	gameState->setGamePosition (currentPosition + velocity);
	
	int playerY = gameState->getPlayer()->getYPosition();
	gameState->getPlayer()->setYPosition(playerY + velocity);

	int computerY = gameState->getComputer()->getYPosition();
	gameState->getComputer()->setYPosition(computerY + velocity);

	for(int i = 0; i < GAME_SIZE ; i++){
		Level* level = gameState->getLevel(i);
		int levelY = level->getLevelYPosition();
		level->updateLevelYPosition(levelY + velocity);		
	}
}

int GameStateManager::getAgentState(Jumper* jumper){
	int stateRepresentation = 0;
	

	int platformId = jumper->getPlatform();
	int levelId = jumper->getLevel();
	int level0State = 0;
	int level1State = 0;
	
	Level* level0 = NULL;
	Level* level1 = NULL;

	std::vector<Level*> levels = gameState->getLevels ();

	if(gameState->getComputer()->getIsOnPlatform()){
		level0 = levels[levelId];
		level0State = level0->getLevelState ();

		if(GAME_SIZE > levelId + 1){
			level1 = levels[levelId + 1];
			level1State = level1->getLevelState ();
		}

	std::cout << std::setbase(10) << "platformId:" << platformId << std::endl;
		
		platformId <<= 10;
		level0State <<= 5;

		if(gameState->getComputer()->getYPosition() < 0){
			stateRepresentation++;
			stateRepresentation <<= 13;
		}
		
		stateRepresentation |= platformId;
		stateRepresentation |= level0State;
		stateRepresentation |= level1State;		
		
	
	}else{
		stateRepresentation = -1;
	}
	
	std::cout << std::setbase(10) << "stateRepresentation =" <<
		stateRepresentation << std::endl;
	return stateRepresentation;
}

int GameStateManager::getLevelPlatforms(Level* level, int agentPlatform){
	int levelState = 0;

	
	for(int i = 0; i < LEVEL_SIZE; i++){
		
	}

	return levelState;
}

void GameStateManager::evaluateWin(){

	if(!gameWon){
		if(gameState->getPlayer()->getLevel() == GAME_SIZE - 1){
			gameState->getPlayer()->setIsWinner(true);
			gameWon = true;
		}else if(gameState->getComputer()->getLevel() == GAME_SIZE - 1){
			gameState->getComputer()->setIsWinner(true);
			gameWon = true;			
		}
	}
}
                                                     